/**
 * 场景查看器 - 演示端主程序
 * 自动加载项目，无需管理界面
 */

import * as THREE from '/lib/three/build/three.module.js';
import { OrbitControls } from '/lib/three/examples/jsm/controls/OrbitControls.js';
import { FBXLoader } from '/lib/three/examples/jsm/loaders/FBXLoader.js';
import { GLTFLoader } from '/lib/three/examples/jsm/loaders/GLTFLoader.js';
import ProjectLoader from './projectLoader.js';
import SceneTreeLoader from './sceneTreeLoader.js';
import ResourcePreloader from './ResourcePreloader.js';

class SceneViewer {
    constructor() {
        this.scene = null;
        this.camera = null;
        this.renderer = null;
        this.controls = null;
        this.clock = new THREE.Clock();
        
        this.projectLoader = new ProjectLoader();
        this.sceneTreeLoader = new SceneTreeLoader();
        this.resourcePreloader = new ResourcePreloader();
        this.projectData = null;
        this.sceneData = null;
        this.config = null;
        
        // 场景树数据
        this.treeStructure = null;  // 树结构（ID和父子关系）
        this.nodesArray = [];       // 节点配置数组
        
        // 辅助对象
        this.gridHelper = null;
        this.axesHelper = null;
        
        // FPS 计算
        this.frameCount = 0;
        this.lastTime = performance.now();
        
        this.init();
    }
    
    /**
     * 初始化
     */
    async init() {
        try {
            console.log('═══════════════════════════════════════════════════════');
            console.log('🚀 演示前端启动');
            console.log('═══════════════════════════════════════════════════════');
            console.log('');
            
            // 步骤 1: 加载配置
            console.log('📋 [步骤 1/5] 加载配置...');
            this.showLoading('正在加载配置...');
            
            const loadResult = await this.projectLoader.init();
            this.projectData = loadResult.project;
            this.sceneData = loadResult.scene;
            this.config = loadResult.config;
            
            console.log('✅ 配置加载完成');
            console.log('   - 模式:', this.config.mode === 'offline' ? '📦 离线模式' : '🌐 在线模式');
            console.log('   - 项目:', this.projectData.name || this.projectData.id);
            console.log('   - 场景:', this.sceneData.name || this.sceneData.id);
            console.log('');
            
            // 步骤 2: 更新标题
            console.log('📝 [步骤 2/5] 更新页面标题...');
            if (this.config.display && this.config.display.title) {
                document.title = this.config.display.title;
                console.log('   - 标题:', this.config.display.title);
            }
            console.log('✅ 页面标题更新完成');
            console.log('');
            
            // 步骤 3: 预加载资源
            console.log('📦 [步骤 3/6] 预加载项目资源...');
            this.showLoading('正在预加载资源...');
            try {
                await this.resourcePreloader.preloadProjectResources(
                    this.config,
                    this.projectData,
                    (loaded, total) => {
                        this.showLoading(`预加载资源: ${loaded}/${total}`);
                    }
                );
                console.log('✅ 资源预加载完成');
            } catch (error) {
                console.error('⚠️ 资源预加载失败，将使用动态加载:', error);
            }
            console.log('');
            
            // 步骤 4: 初始化 Three.js
            console.log('🎨 [步骤 4/6] 初始化 3D 引擎...');
            this.showLoading('正在初始化 3D 场景...');
            this.initThreeJS();
            console.log('✅ Three.js 初始化完成');
            console.log('   - 场景: ✓');
            console.log('   - 相机: ✓');
            console.log('   - 渲染器: ✓');
            console.log('   - 控制器: ✓');
            console.log('   - 灯光: ✓');
            console.log('');
            
            // 步骤 5: 加载场景内容
            console.log('📦 [步骤 5/6] 加载场景内容...');
            this.showLoading('正在加载模型...');
            await this.loadSceneContent();
            console.log('✅ 场景内容加载完成');
            console.log('');
            
            // 步骤 6: 启动渲染循环
            console.log('▶️  [步骤 6/6] 启动渲染循环...');
            this.hideLoading();
            this.animate();
            
            // 监听窗口大小变化
            window.addEventListener('resize', () => this.onWindowResize());
            
            console.log('✅ 渲染循环已启动');
            console.log('');
            console.log('═══════════════════════════════════════════════════════');
            console.log('🎉 场景查看器初始化完成！');
            console.log('═══════════════════════════════════════════════════════');
            console.log('');
            console.log('💡 提示:');
            console.log('   - 左键拖动: 旋转视角');
            console.log('   - 右键拖动: 平移视角');
            console.log('   - 滚轮: 缩放视角');
            console.log('');
            
        } catch (error) {
            console.log('');
            console.log('═══════════════════════════════════════════════════════');
            console.error('❌ 初始化失败');
            console.log('═══════════════════════════════════════════════════════');
            console.error('错误信息:', error.message);
            console.error('错误堆栈:', error.stack);
            console.log('');
            this.showError('加载失败: ' + error.message);
        }
    }
    
    /**
     * 初始化 Three.js
     */
    initThreeJS() {
        console.log('   → 创建 Three.js 场景...');
        const container = document.getElementById('viewer-container');
        
        // 创建场景
        this.scene = new THREE.Scene();
        this.scene.background = new THREE.Color(0x1a1a1a);
        console.log('   → 场景创建完成');
        
        // 创建相机
        const aspect = window.innerWidth / window.innerHeight;
        this.camera = new THREE.PerspectiveCamera(75, aspect, 0.1, 1000);
        this.camera.position.set(5, 5, 5);
        this.camera.lookAt(0, 0, 0);
        console.log('   → 相机创建完成 (位置: 5, 5, 5)');
        
        // 创建渲染器
        this.renderer = new THREE.WebGLRenderer({ antialias: true });
        this.renderer.setSize(window.innerWidth, window.innerHeight);
        this.renderer.setPixelRatio(window.devicePixelRatio);
        this.renderer.shadowMap.enabled = true;
        container.appendChild(this.renderer.domElement);
        console.log('   → 渲染器创建完成 (抗锯齿: 开启, 阴影: 开启)');
        
        // 创建控制器
        this.controls = new OrbitControls(this.camera, this.renderer.domElement);
        this.controls.enableDamping = true;
        this.controls.dampingFactor = 0.05;
        console.log('   → 轨道控制器创建完成 (阻尼: 开启)');
        
        // 添加灯光
        const ambientLight = new THREE.AmbientLight(0x404040, 1);
        this.scene.add(ambientLight);
        
        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
        directionalLight.position.set(10, 10, 10);
        directionalLight.castShadow = true;
        this.scene.add(directionalLight);
        console.log('   → 灯光添加完成 (环境光 + 平行光)');
        
        // 添加网格
        this.gridHelper = new THREE.GridHelper(50, 50, 0x444444, 0x444444);
        this.scene.add(this.gridHelper);
        console.log('   → 网格辅助线添加完成 (50x50)');
        
        // 添加坐标轴
        this.axesHelper = new THREE.AxesHelper(10);
        this.scene.add(this.axesHelper);
        console.log('   → 坐标轴辅助线添加完成');
    }
    
    /**
     * 加载场景内容
     */
    async loadSceneContent() {
        if (!this.sceneData || !this.sceneData.tree) {
            console.warn('   ⚠️  场景树为空，跳过加载');
            return;
        }
        
        console.log('   → 场景数据版本:', this.sceneData.version || '1.0');
        
        // 检查是否有独立的 nodes 数据
        if (this.sceneData.nodes && this.sceneData.nodes.nodes) {
            // 新版格式：tree 和 nodes 已分离
            console.log('   ✓ 使用新版格式 (tree + nodes)');
            this.treeStructure = this.sceneData.tree.root;
            this.nodesArray = this.sceneData.nodes.nodes;
            
            // 将节点数组加载到 SceneTreeLoader 的映射表中
            this.sceneTreeLoader.nodesArray = this.nodesArray;
            this.sceneTreeLoader.nodesMap.clear();
            this.nodesArray.forEach(node => {
                this.sceneTreeLoader.nodesMap.set(node.id, node);
            });
            
        } else {
            // 旧版格式：需要分离 tree 数据
            console.log('   ⚠️  使用旧版格式，自动分离数据...');
            const treeRoot = this.sceneData.tree.root || this.sceneData.tree;
            const { tree, nodes } = this.sceneTreeLoader.loadFromFullTree({ root: treeRoot });
            this.treeStructure = tree;
            this.nodesArray = nodes;
        }
        
        console.log('   ╔═══════════════════════════════════════════════════════╗');
        console.log('   ║  场景树数据结构                                       ║');
        console.log('   ╚═══════════════════════════════════════════════════════╝');
        console.log('   📊 树结构 (只包含ID和父子关系):');
        console.log(this.treeStructure);
        console.log('   📊 节点配置数组 (平面结构):');
        console.log('     - 节点数量:', this.nodesArray.length);
        console.log(this.nodesArray);
        console.log('   ╚═══════════════════════════════════════════════════════╝');
        console.log('');
        
        console.log('   → 开始根据节点配置加载场景...');
        
        if (this.treeStructure.children && this.treeStructure.children.length > 0) {
            console.log(`   → 找到 ${this.treeStructure.children.length} 个顶层节点`);
            let modelCount = 0;
            
            for (const childStructure of this.treeStructure.children) {
                const loaded = await this.loadTreeNodeById(childStructure);
                if (loaded) modelCount++;
            }
            
            console.log(`   → 场景加载完成，共加载 ${modelCount} 个模型`);
        } else {
            console.log('   → 场景树为空，没有需要加载的内容');
        }
    }
    
    /**
     * 根据树结构（只有ID）和节点配置加载节点
     */
    async loadTreeNodeById(structure, depth = 0) {
        const indent = '     ' + '  '.repeat(depth);
        
        // 从节点配置数组中获取完整配置
        const nodeConfig = this.sceneTreeLoader.getNodeById(structure.id);
        
        if (!nodeConfig) {
            console.warn(`${indent}⚠️  节点 ${structure.id} 的配置未找到`);
            return false;
        }
        
        console.log(`${indent}→ 节点: ${nodeConfig.name} (${nodeConfig.type})`);
        
        let loaded = false;
        
        // 如果是模型节点，加载模型
        if (nodeConfig.type === 'model' && nodeConfig.modelPath) {
            console.log(`${indent}  → 加载模型...`);
            loaded = await this.loadModel(nodeConfig);
        } else if (nodeConfig.type === 'group' || nodeConfig.type === 'root') {
            // 创建空的Group对象
            const group = new THREE.Group();
            group.name = nodeConfig.name;
            
            // ✅ 获取 transform 数据（支持新格式 components 和旧格式）
            let transformData = null;
            if (nodeConfig.components) {
                const transformComponent = nodeConfig.components.find(c => c.type === 'transform');
                if (transformComponent) {
                    transformData = {
                        position: transformComponent.position || { x: 0, y: 0, z: 0 },
                        rotation: transformComponent.rotation || { x: 0, y: 0, z: 0 },
                        scale: transformComponent.scale || { x: 1, y: 1, z: 1 }
                    };
                }
            } else if (nodeConfig.transform) {
                // 旧格式兼容
                transformData = nodeConfig.transform;
            }
            
            // ✅ transform 保存的是世界坐标，需要应用为世界坐标
            if (transformData) {
                // 先临时添加到场景，以便计算世界矩阵
                this.scene.add(group);
                
                // 创建世界矩阵
                const worldPosition = new THREE.Vector3(
                    transformData.position.x,
                    transformData.position.y,
                    transformData.position.z
                );
                const worldRotation = new THREE.Euler(
                    transformData.rotation.x,
                    transformData.rotation.y,
                    transformData.rotation.z
                );
                const worldQuaternion = new THREE.Quaternion().setFromEuler(worldRotation);
                const worldScale = new THREE.Vector3(
                    transformData.scale.x,
                    transformData.scale.y,
                    transformData.scale.z
                );
                
                const worldMatrix = new THREE.Matrix4();
                worldMatrix.compose(worldPosition, worldQuaternion, worldScale);
                
                // 如果有父节点，需要转换为本地坐标
                if (group.parent) {
                    const parentWorldMatrix = new THREE.Matrix4();
                    group.parent.updateMatrixWorld(true);
                    parentWorldMatrix.copy(group.parent.matrixWorld);
                    const parentWorldMatrixInverse = new THREE.Matrix4().copy(parentWorldMatrix).invert();
                    
                    const localMatrix = new THREE.Matrix4().multiplyMatrices(parentWorldMatrixInverse, worldMatrix);
                    
                    const localPosition = new THREE.Vector3();
                    const localQuaternion = new THREE.Quaternion();
                    const localScale = new THREE.Vector3();
                    localMatrix.decompose(localPosition, localQuaternion, localScale);
                    
                    group.position.copy(localPosition);
                    group.quaternion.copy(localQuaternion);
                    group.scale.copy(localScale);
                } else {
                    // 没有父节点，直接应用世界坐标
                    group.position.copy(worldPosition);
                    group.quaternion.copy(worldQuaternion);
                    group.scale.copy(worldScale);
                }
            } else {
                // 旧格式：兼容 position/rotation/scale 数组（向后兼容，本地坐标）
                if (nodeConfig.position) {
                    group.position.set(...nodeConfig.position);
                }
                if (nodeConfig.rotation) {
                    group.rotation.set(...nodeConfig.rotation);
                }
                if (nodeConfig.scale) {
                    group.scale.set(...nodeConfig.scale);
                }
                this.scene.add(group);
            }
            
            group.visible = nodeConfig.visible;
            
            console.log(`${indent}  ✓ 创建组节点`);
        }
        
        // 递归加载子节点
        let childrenLoaded = 0;
        if (structure.children && structure.children.length > 0) {
            console.log(`${indent}  → 子节点数: ${structure.children.length}`);
            for (const childStructure of structure.children) {
                const childLoaded = await this.loadTreeNodeById(childStructure, depth + 1);
                if (childLoaded) childrenLoaded++;
            }
        }
        
        return loaded || childrenLoaded > 0;
    }
    
    /**
     * 加载场景树节点（旧方法，保留作为备用）
     */
    async loadTreeNode(node, depth = 0) {
        const indent = '     ' + '  '.repeat(depth);
        
        if (node.type === 'model' && node.modelPath) {
            console.log(`${indent}→ 加载模型: ${node.name || '未命名'}`);
            const success = await this.loadModel(node);
            return success;
        } else {
            console.log(`${indent}→ 节点: ${node.name || '未命名'} (${node.type})`);
        }
        
        // 递归加载子节点
        let childrenLoaded = 0;
        if (node.children && node.children.length > 0) {
            for (const child of node.children) {
                const loaded = await this.loadTreeNode(child, depth + 1);
                if (loaded) childrenLoaded++;
            }
        }
        
        return childrenLoaded > 0;
    }
    
    /**
     * 加载模型
     */
    async loadModel(node) {
        try {
            const modelPath = this.projectLoader.getModelPath(node.modelPath);
            const extension = modelPath.split('.').pop().toLowerCase();
            
            console.log(`       → 文件: ${node.modelPath}`);
            console.log(`       → 类型: ${extension.toUpperCase()}`);
            
            const startTime = performance.now();
            let model;
            
            if (extension === 'fbx') {
                const loader = new FBXLoader();
                model = await new Promise((resolve, reject) => {
                    loader.load(modelPath, resolve, undefined, reject);
                });
            } else if (extension === 'gltf' || extension === 'glb') {
                const loader = new GLTFLoader();
                const gltf = await new Promise((resolve, reject) => {
                    loader.load(modelPath, resolve, undefined, reject);
                });
                model = gltf.scene;
            }
            
            if (model) {
                // ✅ 获取 transform 数据（支持新格式 components 和旧格式）
                let transformData = null;
                if (node.components) {
                    const transformComponent = node.components.find(c => c.type === 'transform');
                    if (transformComponent) {
                        transformData = {
                            position: transformComponent.position || { x: 0, y: 0, z: 0 },
                            rotation: transformComponent.rotation || { x: 0, y: 0, z: 0 },
                            scale: transformComponent.scale || { x: 1, y: 1, z: 1 }
                        };
                    }
                } else if (node.transform) {
                    // 旧格式兼容
                    transformData = node.transform;
                }
                
                // ✅ transform 保存的是世界坐标
                if (transformData) {
                    // 先添加到场景
                    this.scene.add(model);
                    
                    // 创建世界矩阵
                    const worldPosition = new THREE.Vector3(
                        transformData.position.x,
                        transformData.position.y,
                        transformData.position.z
                    );
                    const worldRotation = new THREE.Euler(
                        transformData.rotation.x,
                        transformData.rotation.y,
                        transformData.rotation.z
                    );
                    const worldQuaternion = new THREE.Quaternion().setFromEuler(worldRotation);
                    const worldScale = new THREE.Vector3(
                        transformData.scale.x,
                        transformData.scale.y,
                        transformData.scale.z
                    );
                    
                    const worldMatrix = new THREE.Matrix4();
                    worldMatrix.compose(worldPosition, worldQuaternion, worldScale);
                    
                    // 如果有父节点，转换为本地坐标
                    if (model.parent) {
                        const parentWorldMatrix = new THREE.Matrix4();
                        model.parent.updateMatrixWorld(true);
                        parentWorldMatrix.copy(model.parent.matrixWorld);
                        const parentWorldMatrixInverse = new THREE.Matrix4().copy(parentWorldMatrix).invert();
                        
                        const localMatrix = new THREE.Matrix4().multiplyMatrices(parentWorldMatrixInverse, worldMatrix);
                        
                        const localPosition = new THREE.Vector3();
                        const localQuaternion = new THREE.Quaternion();
                        const localScale = new THREE.Vector3();
                        localMatrix.decompose(localPosition, localQuaternion, localScale);
                        
                        model.position.copy(localPosition);
                        model.quaternion.copy(localQuaternion);
                        model.scale.copy(localScale);
                    } else {
                        // 没有父节点，直接应用世界坐标
                        model.position.copy(worldPosition);
                        model.quaternion.copy(worldQuaternion);
                        model.scale.copy(worldScale);
                    }
                } else {
                    // 旧格式：兼容 position/rotation/scale（向后兼容，本地坐标）
                    if (node.position) {
                        if (Array.isArray(node.position)) {
                            model.position.set(...node.position);
                        } else {
                            model.position.set(node.position.x, node.position.y, node.position.z);
                        }
                    }
                    if (node.rotation) {
                        if (Array.isArray(node.rotation)) {
                            model.rotation.set(...node.rotation);
                        } else {
                            model.rotation.set(node.rotation.x, node.rotation.y, node.rotation.z);
                        }
                    }
                    if (node.scale) {
                        if (Array.isArray(node.scale)) {
                            model.scale.set(...node.scale);
                        } else {
                            model.scale.set(node.scale.x, node.scale.y, node.scale.z);
                        }
                    }
                    this.scene.add(model);
                }
                
                model.name = node.name;
                model.visible = node.visible !== undefined ? node.visible : true;
                
                // 🎯 修复透明材质问题：遍历所有材质，自动检测和修复透明度设置
                model.traverse((child) => {
                    if (child.isMesh && child.material) {
                        const materials = Array.isArray(child.material) ? child.material : [child.material];
                        materials.forEach(mat => {
                            // 检测是否有透明贴图或需要透明度
                            if (mat.alphaMap || mat.transparent || mat.opacity < 1.0) {
                                console.log(`       🎭 检测到透明材质: ${mat.name || '未命名'}`);
                                
                                // 启用透明度
                                mat.transparent = true;
                                
                                // 设置 alphaTest（如果有 alphaMap）
                                if (mat.alphaMap && (mat.alphaTest === undefined || mat.alphaTest === 0)) {
                                    mat.alphaTest = 0.5;
                                    console.log(`       ⚙️  设置 alphaTest = 0.5`);
                                }
                                
                                // 🔧 关键：禁用深度写入，防止透明区域遮挡后面的物体
                                if (mat.depthWrite === undefined || mat.depthWrite === true) {
                                    mat.depthWrite = false;
                                    console.log(`       ⚙️  禁用深度写入 (depthWrite = false)`);
                                }
                                
                                mat.needsUpdate = true;
                            }
                        });
                    }
                });
                
                const loadTime = (performance.now() - startTime).toFixed(2);
                console.log(`       ✓ 加载完成 (耗时: ${loadTime}ms)`);
                return true;
            }
            
            return false;
            
        } catch (error) {
            console.error(`       ✗ 加载失败: ${error.message}`);
            return false;
        }
    }
    
    /**
     * 窗口大小变化
     */
    onWindowResize() {
        this.camera.aspect = window.innerWidth / window.innerHeight;
        this.camera.updateProjectionMatrix();
        this.renderer.setSize(window.innerWidth, window.innerHeight);
    }
    
    /**
     * 显示加载界面
     */
    showLoading(message = '加载中...') {
        const overlay = document.getElementById('loading-overlay');
        const text = document.getElementById('loading-text');
        if (overlay) {
            overlay.style.display = 'flex';
            if (text) text.textContent = message;
        }
    }
    
    /**
     * 隐藏加载界面
     */
    hideLoading() {
        const overlay = document.getElementById('loading-overlay');
        if (overlay) {
            overlay.style.display = 'none';
        }
    }
    
    /**
     * 显示错误
     */
    showError(message) {
        const overlay = document.getElementById('loading-overlay');
        const text = document.getElementById('loading-text');
        if (overlay && text) {
            overlay.style.display = 'flex';
            text.innerHTML = `❌ ${message}<br><br>请检查配置或联系管理员`;
            text.style.color = '#ff4444';
        }
    }
    
    /**
     * 更新 FPS
     */
    updateFPS() {
        this.frameCount++;
        const currentTime = performance.now();
        const elapsed = currentTime - this.lastTime;
        
        if (elapsed >= 1000) {
            const fps = Math.round((this.frameCount * 1000) / elapsed);
            const fpsElement = document.getElementById('fps-counter');
            if (fpsElement) {
                fpsElement.textContent = `FPS: ${fps}`;
            }
            this.frameCount = 0;
            this.lastTime = currentTime;
        }
    }
    
    /**
     * 动画循环
     */
    animate() {
        requestAnimationFrame(() => this.animate());
        
        // 更新控制器
        this.controls.update();
        
        // 渲染场景
        this.renderer.render(this.scene, this.camera);
        
        // 更新 FPS
        this.updateFPS();
    }
}

// 启动查看器
console.log('📌 viewer.js 模块已加载');
console.log('📌 document.readyState:', document.readyState);

if (document.readyState === 'loading') {
    // 文档还在加载中，等待 DOMContentLoaded
    console.log('⏳ 等待 DOMContentLoaded 事件...');
    window.addEventListener('DOMContentLoaded', () => {
        console.log('✅ DOMContentLoaded 事件触发');
        window.sceneViewer = new SceneViewer();  // 暴露到 window，供其他模块访问
    });
} else {
    // 文档已经加载完成，直接启动
    console.log('✅ 文档已加载完成，立即启动查看器');
    window.sceneViewer = new SceneViewer();  // 暴露到 window，供其他模块访问
}

